package com.chenl.interview.sentinel;

import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
import com.chenl.interview.utils.BlackIpUtils;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

@Component
@Slf4j
public class SentinelFlowRuleDataSource implements InitializingBean {

    @NacosInjected
    private ConfigService configService;

    @Override
    public void afterPropertiesSet() throws Exception {
        // 从 Nacos 获取初始规则配置
        String rulesJson = configService.getConfig("flow", "sentinel_rule", 5000);
        List<FlowRule> rules = JSON.parseArray(rulesJson, FlowRule.class);
        FlowRuleManager.loadRules(rules);

        log.info("限流规则监听器启动");
        // 添加监听器，实时更新规则
        String config = configService.getConfigAndSignListener("flow", "sentinel_rule", 3000L, new Listener() {
            final ThreadFactory threadFactory = new ThreadFactory() {
                private final AtomicInteger poolNumber = new AtomicInteger(1);
                @Override
                public Thread newThread(@NotNull Runnable r) {
                    Thread thread = new Thread(r);
                    thread.setName("refresh-ThreadPool" + poolNumber.getAndIncrement());
                    return thread;
                }
            };
            final ExecutorService executorService = Executors.newFixedThreadPool(1, threadFactory);

            @Override
            public Executor getExecutor() {
                return executorService;
            }

            // 监听规则变化
            @Override
            public void receiveConfigInfo(String configInfo) {
                List<FlowRule> updatedRules = JSON.parseArray(configInfo, FlowRule.class);
                FlowRuleManager.loadRules(updatedRules);
                log.info("监听到限流配置信息变化：{}", configInfo);
            }
        });

        log.info("限流规则:{}",rules);
    }
}
